﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public enum PigAiState
{
    Standby = 0,        //待机状态,呆在原地什么也不做
    Patrol = 1,         //巡逻状态,左右移动巡逻，发现玩家后进行追击
    Chase = 3,          //追击状态,尝试移动到玩家身边并进行攻击
}


public class AI : MonoBehaviour
{
    [SerializeField] private float sight_dis;           //视线范围
    [SerializeField] private float attack_range;        //判定是否进行攻击的范围
    [SerializeField] private LayerMask layer01;         //玩家所在图层
    [SerializeField] private float preTime_Attack;      //攻击前摇
    [SerializeField] private PigAiState startState;     //初始状态

    float downTime_Attack;                              //攻击倒计时


    private GameObject chaseTarget;
    private PigAiState pigAiState;
    private Behavior behavior;
    private Rigidbody2D rbody;

    // Start is called before the first frame update
    void Start()
    {
        pigAiState = startState;
        behavior = this.gameObject.GetComponent<Behavior>();
        rbody = this.gameObject.GetComponent<Rigidbody2D>();
        downTime_Attack = -1f;
    }

    private void FixedUpdate()
    {
        switch (pigAiState)
        {
            case PigAiState.Standby:
                behavior.Move(0);
                if (CheckSight())
                {
                    pigAiState = PigAiState.Chase;
                }
                break;
            case PigAiState.Patrol:
                if (CheckSight())
                {
                    pigAiState = PigAiState.Chase;
                }
                else
                {
                    if (behavior.CanGoAhead())
                    {
                        if (rbody.velocity.x == 0)
                        {
                            Debug.Log(transform.localScale.x);
                            if (transform.localScale.x > 0) behavior.Move(1f);
                            else behavior.Move(-1f);
                        }
                    }
                    else
                    {
                        if (transform.localScale.x > 0) behavior.Move(-1f);
                        else behavior.Move(1f);
                    }
                }
                break;
            case PigAiState.Chase:
                if (chaseTarget != null)
                {
                    //攻击倒计时为-1说明未准备攻击,这时候尝试靠近目标
                    if (downTime_Attack == -1f)
                    {
                        if (PlayerInAttackArea())
                        {
                            //Debug.Log("preTime_Attack");
                            downTime_Attack = preTime_Attack;
                            behavior.Move(0);
                        }
                        else
                        {
                            RunToTarget();
                        }
                    }
                    else
                    {
                        //Debug.Log(downTime_Attack);
                        if (behavior.IsAttack() == false)
                        {
                            //Debug.Log(downTime_Attack);
                            downTime_Attack -= Time.fixedDeltaTime;
                            if (downTime_Attack <= 0f)
                            {
                                behavior.Attack();
                                downTime_Attack = -1f;
                            }
                        }
                    }
                }
                else
                {
                    pigAiState = PigAiState.Patrol;
                }
                break;
        }
    }

    /// <summary>
    /// 尝试朝目标移动
    /// </summary>
    void RunToTarget()
    {
        Vector2 pos, ply_pos;
        pos = behavior.GetCenterPos();
        ply_pos = chaseTarget.GetComponent<Behavior>().GetCenterPos();
        if (pos.x < ply_pos.x)
        {
            behavior.Move(1f);
        }
        else
        {
            behavior.Move(-1f);
        }
    }

    /// <summary>
    /// 判断追踪目标是否进入攻击范围
    /// </summary>
    bool PlayerInAttackArea()
    {
        Vector2 pos, ply_pos, sz, ply_sz;
        pos = behavior.GetCenterPos();
        ply_pos = chaseTarget.GetComponent<Behavior>().GetCenterPos();
        sz = gameObject.GetComponent<BoxCollider2D>().size;
        ply_sz = chaseTarget.GetComponent<BoxCollider2D>().size;

        if (transform.localScale.x > 0)
        {
            if ((pos.x < ply_pos.x) && (pos.x + sz.x/2 + attack_range >= ply_pos.x - ply_sz.x/2))
            {
                return true;
            }
        }
        else
        {
            if ((pos.x > ply_pos.x) && (pos.x - sz.x/2 - attack_range <= ply_pos.x + ply_sz.x/2))
            {
                return true;
            }
        }

        return false;
    }

    /// <summary>
    /// 判断视线内是否可以看到玩家
    /// </summary>
    /// <returns></returns>
    bool CheckSight()
    {
        Vector2 direction = (transform.localScale.x > 0) ? (Vector2.right) : (Vector2.left);
        RaycastHit2D hit = Physics2D.Raycast(transform.position, direction, sight_dis, layer01);

        if (hit.collider != null)
        {
            chaseTarget = hit.collider.gameObject;
            return true;
        }
        return false;
    }

    private void OnDrawGizmosSelected()
    {
        if (transform.localScale.x > 0)
            Gizmos.DrawLine(transform.position, transform.position + new Vector3(sight_dis, 0, 0));
        else if (transform.localScale.x < 0)
            Gizmos.DrawLine(transform.position, transform.position + new Vector3(-sight_dis, 0, 0));
    }
}
